// Copyright (c) 2020 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

/**
*@describe:
*@author wfl19/Kristas
*@date 2021/04/10
 */

package datasource_bak

import (
	"database/sql"
	"errors"
	"fmt"
	"gitee.com/kristas/booting-go/framework/data/tunnel_client"
	"github.com/go-sql-driver/mysql"
	"time"
)

func init() {
	UseDataBaseHandler("mysql", mysqlHandler)
}

func mysqlHandler(d *Starter, config Datasource) (*sql.DB, error) {
	switch config.GetTunnel() {
	case "ssh":
		mysql.RegisterDialContext("mysql+ssh", d.SSHDialer.Dial)
	case "tcp":
		mysql.RegisterDialContext("mysql+tcp", d.TCPDialer.Dial)
	}

	dsn := fmt.Sprintf("%s:%s@mysql+%s(%s)%s",
		config.GetUsername(), config.GetPassword(), config.GetTunnel(), config.GetHost(), config.GetDatabase())
	conn, err := sql.Open("mysql", dsn)
	if err != nil {
		return nil, errors.New(fmt.Sprintf("Failed to open mysql connection:\ncaused by:\ndsn: %s\n%s", dsn, err.Error()))
	}
	if !config.IsLazyFetch() {
		if err = conn.Ping(); err != nil {
			return nil, errors.New(fmt.Sprintf("ping mysql failed:\ncaused by:\n%s", err.Error()))
		}
	}
	initConn(config, conn)
	return conn, nil
}

func initConn(config Datasource, conn *sql.DB) {
	if config.GetConnMaxLifeTime() != 0 {
		conn.SetConnMaxLifetime(time.Second * time.Duration(config.GetConnMaxLifeTime()))
	}
	if config.GetConnMaxIdleTime() != 0 {
		conn.SetConnMaxIdleTime(time.Second * time.Duration(config.GetConnMaxIdleTime()))
	}
	if config.GetMaxIdleConns() != 0 {
		conn.SetMaxIdleConns(config.GetMaxIdleConns())
	}
	if config.GetMaxOpenConns() != 0 {
		conn.SetMaxOpenConns(config.GetMaxOpenConns())
	}
}

func mysqlDriver(dialer tunnel_client.Dialer, config Datasource) (*sql.DB, error) {
	mysql.RegisterDialContext("mysql+"+config.GetTunnel(), dialer.Dial)

	dsn := fmt.Sprintf("%s:%s@mysql+%s(%s)%s",
		config.GetUsername(), config.GetPassword(), config.GetTunnel(), config.GetHost(), config.GetDatabase())
	conn, err := sql.Open("mysql", dsn)
	if err != nil {
		return nil, errors.New(fmt.Sprintf("Failed to open mysql connection:\ncaused by:\ndsn: %s\n%s", dsn, err.Error()))
	}
	if !config.IsLazyFetch() {
		if err = conn.Ping(); err != nil {
			return nil, errors.New(fmt.Sprintf("ping mysql failed:\ncaused by:\n%s", err.Error()))
		}
	}
	initConn(config, conn)
	return conn, nil
}
